//
//  DataBaseManager.m
//  1026FMDB
//
//  Created by Haozhong Chen on 2016/10/26.
//  Copyright © 2016年 Haozhong Chen. All rights reserved.
//

#import "DataBaseManager.h"
#import <FMDB.h>


@implementation DataBaseManager

static id _instance;
//static FMDatabaseQueue*_dataBaseQueue;

#pragma mark - 创建单例对象
+(instancetype)sharedManager
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance=[[DataBaseManager alloc]init];
    });
    return _instance;
}

#pragma mark - 单例对象的init方法
//重写单例对象的init方法,在方法内部创建一个DataBase队列,init初始化方法只会执行一次,所以该队列也是单例的
-(instancetype)init
{
    if (self=[super init]) {
        
//        在沙盒中的指定路径创建一个指定文件名的数据库文件,并打开数据库
        //通过指定的位置的数据库文件创建队列,如果数据库不存在,就创建一个数据库并打开
        NSString*cachePath=[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
        NSString*filePath=[cachePath stringByAppendingString:@"/test.db"];
        
        _dataBaseQueue=[FMDatabaseQueue databaseQueueWithPath:filePath];
        
//        第一次创建队列和数据库,即初始化表
        [self creatTables];
    };
    return self;
}



#pragma mark - 表的初始化操作
-(void)creatTables
{
    NSString*filePath=[[NSBundle mainBundle] pathForResource:@"main.sql" ofType:nil];
    NSString*sqlString=[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
    
//    执行多个sql语句
    [_dataBaseQueue inDatabase:^(FMDatabase *db) {
        BOOL isSucceed=[db executeStatements:sqlString];
        NSLog(@"%@",isSucceed?@"Succeed":@"Failed");
    }];
    
    NSString*filePathSettings=[[NSBundle mainBundle] pathForResource:@"receiving_settings.sql" ofType:nil];
    NSString*sqlStringSettings=[NSString stringWithContentsOfFile:filePathSettings encoding:NSUTF8StringEncoding error:NULL];
    
    [_dataBaseQueue inDatabase:^(FMDatabase *db) {
        BOOL isSucceed=[db executeStatements:sqlStringSettings];
        NSLog(@"%@",isSucceed?@"Succeed":@"Failed");
    }];
    
}
-(BOOL)executeSQLStatements:(NSString*)sqlString
{
    __block BOOL isSucceed=NO;
    //    执行一条sql语句
    [_dataBaseQueue inDatabase:^(FMDatabase *db) {
        isSucceed=[db executeStatements:sqlString];
    }];
    return isSucceed;
}



#pragma mark - 数据库更新操作
-(BOOL)executeSQLString:(NSString*)sqlString
{
    __block BOOL isSucceed=NO;
//    执行一条sql语句
    [_dataBaseQueue inDatabase:^(FMDatabase *db) {
        isSucceed=[db executeUpdate:sqlString];
    }];
    return isSucceed;
}

#pragma mark - 数据库查询操作

-(NSArray<NSDictionary*>*)queryRecords:(NSString*)sqlString
{
    NSMutableArray*mutableArray=[NSMutableArray array];
    [_dataBaseQueue inDatabase:^(FMDatabase *db){
//      获取查询结果
        FMResultSet*resultSet=[db executeQuery:sqlString];
        //一次查询一行
        //判断是否有一下行
        
        /** Retrieve next row for result set.
         
         You must always invoke `next` or `nextWithError` before attempting to access the values returned in a query, even if you're only expecting one.
         
         在尝试接收查询返回的结果之前,必须调用next或者nextWithError方法,即时你期待的查询结果只有一条
         @return `YES` if row successfully retrieved; `NO` if end of result set reached
         @see hasAnotherRow
         
         返回值Yes表示成功检索到一行新的数据,返回值No表示当前上一个返回行已经是检索结果的结尾
         */
        while ([resultSet next])
        {
            NSMutableDictionary*mutableDict=[NSMutableDictionary dictionary];
            //获取每一行的列数
            int columnCount=resultSet.columnCount;
//            遍历该行的每一列
            for (int i=0; i<columnCount; i++)
            {
                NSString*keyName=[resultSet columnNameForIndex:i];
                id valueObject=[resultSet objectForColumnName:keyName];
//                将每一行的键值存到一个可变字典
                [mutableDict setObject:valueObject forKey:keyName];
            }
//            将存储一行数据的字典加入一个字典数组
            [mutableArray addObject:mutableDict.copy];
        }
    }];
    return mutableArray.copy;
}

@end
